﻿using RXY_Mall.Application.AllFinance.Dto;
using RXY_Mall.Core;
using RXY_Mall.Core.Tool;
using RXY_Mall.Domain;
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Threading.Tasks;

namespace RXY_Mall.Application.AllFinance
{
    public class FinanceService : RXY_MallAppServiceBase, IFinanceService
    {
        public async Task<Response<int>> CheckShopWithdrawal(int managerId, int id, int status, string remark)
        {
            var model = db.gw_shop_finance_withdrawals
                .Include(u => u.gw_shop)
                .Include(u => u.gw_shop.gw_shop_property)
                .FirstOrDefault(i => i.id == id);
            if (model == null)
            {
                return ReturnError<int>("信息不存在");
            }
            if (status == 1 || model.status == (byte)status)
            {
                return ReturnError<int>("审核状态未改变");
            }
            var log = db.gw_shop_finance_logs.FirstOrDefault(i => i.relation_no == model.withdrawal_no && i.trade_type == 20 && i.in_out == 2);
            if (log == null)
            {
                return ReturnError<int>("信息异常！");
            }
            else
            {
                if (status == 3)
                {
                    //通知
                    var message = new gw_message()
                    {
                        user_id = 0,
                        shop_id = model.shop_id,
                        type = 4,
                        title = "提现成功通知",
                        summary = "您的提现申请已通过，到账成功！",
                        content = "提现金额￥ " + model.money + " 元",
                        picture_url = "",
                        status = 1,
                        remark = "",
                        deleted = false,
                        add_time = DateTime.Now,
                    };
                    db.gw_messages.Add(message);
                    log.remark = "成功";
                }
                if (status == 4)
                {
                    var money = log.before - log.end;
                    // 通知
                    var message = new gw_message()
                    {
                        user_id = 0,
                        shop_id = model.shop_id,
                        type = 4,
                        title = "提现失败通知",
                        summary = "您的提现申请被拒绝，提现金额已退回！",
                        content = "拒绝原因" + remark + "；退回金额￥" + money + "元",
                        picture_url = "",
                        status = 1,
                        remark = "",
                        deleted = false,
                        add_time = DateTime.Now,
                    };
                    db.gw_messages.Add(message);
                    log.remark = "拒绝";
                    var record = new gw_shop_finance_log()
                    {
                        shop_id = log.shop_id,
                        relation_id = model.id,
                        trade_type = 22,
                        currency = 1,
                        in_out = 1,
                        before = (decimal)model.gw_shop.gw_shop_property.balances,
                        end = (decimal)model.gw_shop.gw_shop_property.balances + money,
                        remark = "拒绝提现",
                        add_time = DateTime.Now,
                        order_no = "",
                        relation_no = model.withdrawal_no,
                        log_no = "FL" + DateTime.Now.ToString("yyMMddHHmmss") + RandomHelper.CreateRandomValue(6),
                    };
                    db.gw_shop_finance_logs.Add(record);
                    model.gw_shop.gw_shop_property.balances += money;
                }

            }

            model.status = (byte)status;
            model.remark = remark;
            model.handling_id = managerId;
            model.handling_time = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
            await db.SaveChangesAsync();
            LogHelper.WriteLog("管理员" + managerId + "审核：改变商家" + id + "提现状态为" + status);
            return ReturnSuccess<int>(1);
        }

        public async Task<Response<int>> CheckUserWithdrawal(int managerId, int id, int status, string remark, string dismiss_reason)
        {
            var model = db.gw_finance_withdraws
                .Include(u => u.gw_user)
                .Include(u => u.gw_user.gw_finance_property)
                .FirstOrDefault(i => i.id == id);
            if (model == null)
            {
                return ReturnError<int>("信息不存在");
            }
            if (status == 1 || model.status == (byte)status)
            {
                return ReturnError<int>("审核状态未改变");
            }
            if (status == 2)
            {
                //通知
                var message = new gw_message()
                {
                    user_id = model.user_id,
                    type = 4,
                    title = "提现成功通知",
                    summary = "您的提现申请已通过，到账成功！",
                    content = "提现金额￥ " + model.money + " 元",
                    picture_url = "",
                    status = 0,
                    remark = "",
                    deleted = false,
                    add_time = DateTime.Now,
                };
                db.gw_messages.Add(message);
            }
            if (status == 3)
            {
                //通知
                var message = new gw_message()
                {
                    user_id = model.user_id,
                    type = 4,
                    title = "提现失败通知",
                    summary = "您的提现申请被拒绝，提现金额已退回！",
                    content = "拒绝原因" + dismiss_reason + "；退回金额￥" + model.amount + "元（提现金额￥ " + model.money + " 元 + 手续费￥" + (model.amount - model.money) + " 元）",
                    picture_url = "",
                    status = 0,
                    remark = "",
                    deleted = false,
                    add_time = DateTime.Now,
                };
                db.gw_messages.Add(message);
                model.gw_user.gw_finance_property.balance += model.amount;
                db.Entry(model.gw_user.gw_finance_property).Property(p => p.balance).IsModified = true;
                //资金变动记录
                var log = new gw_finance_property_log()
                {
                    order_no = model.order_no,
                    user_id = model.user_id,
                    trade_type = 18,
                    currency = 1,
                    type = 1,
                    value = model.amount,
                    last_value = model.gw_user.gw_finance_property.balance,
                    add_time = DateTime.Now,
                    remark = "提现拒绝退回金额￥" + model.amount + "元（提现金额￥ " + model.money + " 元 + 手续费￥" + (model.amount - model.money) + " 元）",
                };
                db.gw_finance_property_logs.Add(log);

            }
            model.status = (byte)status;
            model.remark = remark;
            model.update_time = DateTime.Now;
            model.dismiss_reason = dismiss_reason;
            await db.SaveChangesAsync();
            LogHelper.WriteLog("管理员" + managerId + "审核：改变用户" + id + "提现状态为" + status);
            return ReturnSuccess<int>(1);
        }

        public IList<ShopWithdrawalDto> GetShopWithdrawalByPage(int iDisplayStart, int iDisplayLength, string dateMin, string dateMax, string code, int status, string shopName, out int totalCount)
        {
            iDisplayLength = iDisplayLength < 1 ? 10 : iDisplayLength;
            DateTime dtMin = DateTime.MinValue;
            DateTime dtMax = DateTime.MaxValue;
            var list = db.gw_shop_finance_withdrawals
                .Include(u => u.gw_shop)
                .Select(item => new ShopWithdrawalDto
                {
                    id = item.id,
                    shop_id = item.shop_id,
                    shop_name = item.gw_shop.name,
                    company_name = item.company_name,
                    money = item.money,
                    bank_name = item.bank_name,
                    bank_cardno = item.bank_cardno,
                    account_holder = item.account_holder,
                    fee_rate = item.fee_rate,
                    fee = item.fee,
                    status = item.status,
                    remark = item.remark,
                    add_time = item.add_time,
                    withdrawal_no = item.withdrawal_no,
                    handling_time = item.handling_time
                });
            if (status > -1)
            {
                list = list.Where(m => m.status == status);
            }
            if (!string.IsNullOrWhiteSpace(code))
            {
                list = list.Where(m => m.withdrawal_no.Contains(code));
            }
            if (!string.IsNullOrWhiteSpace(shopName))
            {
                list = list.Where(m => m.shop_name.Contains(shopName));
            }
            if (!string.IsNullOrWhiteSpace(dateMin))
            {
                dtMin = DateTime.Parse(dateMin);
            }
            if (!string.IsNullOrWhiteSpace(dateMax))
            {
                dtMax = DateTime.Parse(dateMax).Date.AddDays(1); ;
            }
            list = list.Where(m => m.add_time >= dtMin && m.add_time <= dtMax);
            totalCount = list.Count();
            list = list.OrderBy(m => m.status).ThenByDescending(i => i.add_time).Skip(iDisplayStart).Take(iDisplayLength);
            return list.ToList();
        }

        public IList<UserVipDto> GetUserVipByPage(int iDisplayStart, int iDisplayLength, string dateMin, string dateMax, string payNo, int pay_type, string userName, string realName, out int totalCount)
        {
            iDisplayLength = iDisplayLength < 1 ? 10 : iDisplayLength;
            DateTime dtMin = DateTime.MinValue;
            DateTime dtMax = DateTime.MaxValue;
            var list = db.gw_order_members
                .Include(u => u.gw_user)
                .Where(i => i.status == 10)
                .Select(item => new UserVipDto
                {
                    id = item.id,
                    user_id = item.user_id,
                    user_name = item.gw_user.name,
                    nick_name = item.gw_user.nick_name,
                    real_name = item.gw_user.real_name,
                    start_time = item.gw_user.start_time,
                    end_time = item.gw_user.end_time,
                    order_no = item.order_no,
                    buy_type = item.buy_type,
                    buy_year = item.buy_year,
                    pay_type = item.pay_type,
                    year_money = item.year_money,
                    pay_no = item.pay_no,
                    pay_time = item.pay_time,
                    amount = item.amount,
                    status = item.status,
                    remark = item.remark,
                    add_time = item.add_time,
                });
            if (pay_type > -1)
            {
                list = list.Where(m => m.pay_type == pay_type);
            }
            if (!string.IsNullOrWhiteSpace(payNo))
            {
                list = list.Where(m => m.pay_no.Contains(payNo));
            }
            if (!string.IsNullOrWhiteSpace(userName))
            {
                list = list.Where(m => m.user_name.Contains(userName));
            }
            if (!string.IsNullOrWhiteSpace(realName))
            {
                list = list.Where(m => m.real_name.Contains(realName));
            }
            if (!string.IsNullOrWhiteSpace(dateMin))
            {
                dtMin = DateTime.Parse(dateMin);
            }
            if (!string.IsNullOrWhiteSpace(dateMax))
            {
                dtMax = DateTime.Parse(dateMax).Date.AddDays(1);
            }
            if (dateMin != "" || dateMax != "")
            {
                list = list.Where(m => m.pay_time >= dtMin && m.pay_time <= dtMax);
            }
            totalCount = list.Count();
            list = list.OrderByDescending(i => i.add_time).Skip(iDisplayStart).Take(iDisplayLength);
            return list.ToList();
        }

        public IList<UserWithdrawalDto> GetUserWithdrawalByPage(int iDisplayStart, int iDisplayLength, string dateMin, string dateMax, string code, int status, string userName, string realName, out int totalCount)
        {
            iDisplayLength = iDisplayLength < 1 ? 10 : iDisplayLength;
            DateTime dtMin = DateTime.MinValue;
            DateTime dtMax = DateTime.MaxValue;
            var list = db.gw_finance_withdraws
                .Include(u => u.gw_user)
                .Select(item => new UserWithdrawalDto
                {
                    id = item.id,
                    user_id = item.user_id,
                    nick_name = item.gw_user.nick_name,
                    user_name = item.gw_user.name,
                    real_name = item.gw_user.real_name,
                    order_no = item.order_no,
                    bank_name = item.bank_name,
                    card_no = item.card_no,
                    bank_address = item.bank_address,
                    bank_branch = item.bank_branch,
                    account_holder = item.account_holder,
                    mobile = item.mobile,
                    type = item.type,
                    money = item.money,
                    service_fee = item.service_fee,
                    amount = item.amount,
                    status = item.status,
                    remark = item.remark,
                    add_time = item.add_time,
                    dismiss_reason = item.dismiss_reason,
                    update_time = item.update_time
                });
            if (status > -1)
            {
                list = list.Where(m => m.status == status);
            }
            if (!string.IsNullOrWhiteSpace(code))
            {
                list = list.Where(m => m.order_no.Contains(code));
            }
            if (!string.IsNullOrWhiteSpace(userName))
            {
                list = list.Where(m => m.user_name.Contains(userName));
            }
            if (!string.IsNullOrWhiteSpace(realName))
            {
                list = list.Where(m => m.real_name.Contains(realName));
            }
            if (!string.IsNullOrWhiteSpace(dateMin))
            {
                dtMin = DateTime.Parse(dateMin);
            }
            if (!string.IsNullOrWhiteSpace(dateMax))
            {
                dtMax = DateTime.Parse(dateMax).Date.AddDays(1); ;
            }
            list = list.Where(m => m.add_time >= dtMin && m.add_time <= dtMax);
            totalCount = list.Count();
            list = list.OrderBy(m => m.status).ThenByDescending(i => i.add_time).Skip(iDisplayStart).Take(iDisplayLength);
            return list.ToList();
        }
    }
}
